package com.hp.bon.sgw.wh.channel.handler;

import com.google.gson.Gson;
import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.MessageType;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.domain.MessageDetail;
import com.hp.bon.sgw.threads.MessageDetailCacheManager;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.bon.sgw.wh.bean.QueryBalanceResponse;
import com.hp.ocs.diameter.message.Message;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.*;

public class QueryBalanceHandle implements IAsynCallHandler {
	private static final Logger _log = LoggerFactory.getLogger(QueryBalanceHandle.class);
	private PrintStream printStream;
	public QueryBalanceHandle(PrintStream printStream) {
		this.printStream = printStream;
	}

	@Override
	public int getProtocolType() {
		return 0;
	}

	@Override
	public void onCallResult(CallParam callParam) {
		XmlMessage ack = null;
		Object response = null;
		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}
		if (response == null) {
			int _retcodeTmp = callParam.getRetCode() == 3002 ? 11202 : callParam.getRetCode();
			ack = SoapChannel.createERRAnwser(callParam.getSessionId(), _retcodeTmp, callParam.getResultMsg());
			callParam.setServiceResultCode(_retcodeTmp);// 11203
		} else {
			if (response instanceof Message) {// CCA -> XML
				ack = BuzProcessorManager.getInstance().convertMessageToAck(callParam);
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				_log.warn("unknown response type:" + callParam.getResponse().getClass().getName());
			}
		}
		try {
			String respXML = convertResponseString(ack, callParam.getServiceResultCode());
			byte[] resp = respXML.getBytes("UTF-8");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();
			callParam.setResponse(ack);
			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库
				MessageDetail detail = new MessageDetail();
				detail.setBusinessCallId(callParam.getBussinessCallId());
				detail.setSessionId(callParam.getSessionId());
				detail.setServiceContextId(callParam.getServiceContextId());
				detail.setMessageType(MessageType.WSA);
				detail.setDetails(ack.getDATA());
				detail.setMsgTime(new Date(ack.getMsgTime()));
				detail.setOpType("send");
				detail.setHostId(callParam.getUserName());
				MessageDetailCacheManager.getInstance().add(detail);
			}
			TaskManager.taskProcess(callParam);
			_log.info("http response(returnBalance) " + respXML);
		} catch (UnsupportedEncodingException e) {
			_log.info("convertResponseString UnsupportedEncodingException error,msg=" + e.getMessage());
		} catch (IOException e) {
			_log.info("convertResponseString IOException,msg=" + e.getMessage());
		}
	}

	
	
	/**
	 * 从Message中解析出需要的数据，并拼接成json字符串
	 * @param answer
	 * @param serviceResultCode
	 * @return
	 */
	private String convertResponseString(XmlMessage ack, int serviceResultCode) {
		_log.info("QueryBalanceHandle serviceResultCode = {}", serviceResultCode);
		String response = "";
		Map<String, Object> data = new HashMap<String, Object>();
		if (serviceResultCode == 0) { 
			response = ack.getDATA();
			XStream xstream2 = new XStream(new DomDriver());
	        xstream2.alias("QueryBalanceResponse", QueryBalanceResponse.class);
	        xstream2.alias("balanceQuery", QueryBalanceResponse.BalanceQuery.class);
	        
	        
	        xstream2.addImplicitCollection(QueryBalanceResponse.class, "balanceQuerys");//隐式集合 隐藏contentslist
	        
	        QueryBalanceResponse queryBalanceResponse = (QueryBalanceResponse) xstream2.fromXML(response);

	        
	        if(queryBalanceResponse==null) {
	        	data.put("realBalance","0");
				data.put("areaCode","0");
				data.put("queryFlag","0");
				data.put("queryItemType","");
				data.put("PaymentFlag",""); 
				data.put("BalanceQuery","");
				data.put("resultCode", "-1");
				data.put("resultMsg", "输入参数解析错误"); 
			}else{
				data.put("realBalance",queryBalanceResponse.getRealBalance());
				data.put("areaCode",queryBalanceResponse.getAreaCode());
				data.put("queryFlag",queryBalanceResponse.getQueryFlag());
				data.put("queryItemType",queryBalanceResponse.getQueryItemType());
				data.put("PaymentFlag",queryBalanceResponse.getPaymentFlag());
				
				List<Map<String, Object>> BalanceQuerys = new ArrayList<Map<String,Object>>();
				
				List<QueryBalanceResponse.BalanceQuery>balanceQuerys = queryBalanceResponse.getBalanceQuery();
				if(!CollectionUtils.isEmpty(balanceQuerys)) {
					for(QueryBalanceResponse.BalanceQuery balanceQuery:balanceQuerys) {
						Map<String, Object> BalanceQuery = new HashMap<String, Object>();
						
						BalanceQuery.put("acctId",balanceQuery.getAcctId());
						BalanceQuery.put("prodInstId",balanceQuery.getProdInstId());
						BalanceQuery.put("accNbr",balanceQuery.getAccNbr());
						BalanceQuery.put("acctBalanceId",balanceQuery.getAcctBalanceId());
						BalanceQuery.put("desc",balanceQuery.getDesc());
						BalanceQuery.put("balance",balanceQuery.getBalance());
						BalanceQuery.put("available",balanceQuery.getAvailable());
						BalanceQuery.put("cycleType",balanceQuery.getCycleType());
						BalanceQuery.put("shareRuleFlag",balanceQuery.getShareRuleFlag());
						BalanceQuery.put("used",balanceQuery.getUsed());
						BalanceQuery.put("cycleUpper",balanceQuery.getCycleUpper());
						BalanceQuery.put("state",balanceQuery.getState());
						BalanceQuery.put("reserveBalance",balanceQuery.getReserveBalance());
						BalanceQuery.put("effDate",balanceQuery.getEffDate());
						BalanceQuery.put("expDate",balanceQuery.getExpDate());
						BalanceQuery.put("balanceTypeFlag",balanceQuery.getBalanceTypeFlag());
						BalanceQuerys.add(BalanceQuery);
					}
				}
				data.put("balanceQuery",BalanceQuerys);
				
				data.put("resultCode","0");
				data.put("resultMsg","SUCCESS");
				
				
			}
			
			
			_log.info("AccuUseQryHandle convertResponseString = {}", response);
		} else {
			_log.info("AccuUseQryHandle convertResponseString = {}", response);
		}
//		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
//		list.add(returnPlanInfoMap);
//		data.put("ReturnPlanInfo", list);
//		Gson gson = new Gson();
//		response = gson.toJson(data);
		Gson gson = new Gson();
		response = gson.toJson(data);
		return response; 
	}

	 
	

}
